#ifndef __VBASE_H__
#define __VBASE_H__
#include "VPlatform.h"
#include "VMemory.h"
#include "VTemplate.h"
#include "VMath.h"
#include "VName.h"
#include "VIOStream.h"

#define VFIELD_OFFSET(Class, Field) ((unsigned int)((void*)&(((Class*)0)->Field)))

//
class VApi VRefTarget
{
	int m_RefCnt;
public:
	inline VRefTarget():m_RefCnt(0)
	{
	}
	virtual ~VRefTarget()
	{
	}
	virtual void DeleteThis()
	{
		delete this;
	}
	inline int NumRefs() const { return m_RefCnt; }
	inline void AddRef() { ++m_RefCnt; }
	inline void Release() 
	{
		if ((--m_RefCnt) == 0)
		{
			DeleteThis();
		}
	}
};

template <class T> 
class VSmartPtr 
{
private:
	T* m_pObj;
public:
	VSmartPtr() : m_pObj(NULL) {}
	inline VSmartPtr(T* p_)
	{
		m_pObj = p_;
		if (m_pObj)
			m_pObj->AddRef();
	}

	inline VSmartPtr(const VSmartPtr &p_)
	{
		m_pObj = p_.m_pObj;
		if (m_pObj)
			m_pObj->AddRef();
	}
	inline ~VSmartPtr()
	{
		if (m_pObj)
			m_pObj->Release();
	}
	inline operator T*() const { return m_pObj; }
	inline T& operator*() const { return *m_pObj; }
	inline T* operator->(void) const { return m_pObj; }
	inline VSmartPtr&  operator=(T* newp)
	{
		if (newp)
			newp->AddRef();
		if (m_pObj)
			m_pObj->Release();
		m_pObj = newp;
		return *this;
	}
	inline VSmartPtr&  operator=(const VSmartPtr &newp)
	{
		if (newp.m_pObj)
			newp.m_pObj->AddRef();
		if (m_pObj)
			m_pObj->Release();
		m_pObj = newp.m_pObj;
		return *this;
	}
	inline bool  operator ==(T* p2) const 
	{
		return m_pObj == p2;
	};
	inline bool  operator ==(const VSmartPtr &p2) const 
	{
		return m_pObj == p2.m_pObj;
	};
	inline bool  operator !=(T* p2) const 
	{
		return m_pObj != p2;
	};
	inline bool  operator !=(const VSmartPtr &p2) const 
	{
		return m_pObj != p2.m_pObj;
	};
	inline bool  operator <(const T* p2) const 
	{
		return m_pObj < p2;
	};
	inline bool  operator >(const T* p2) const 
	{
		return m_pObj > p2;
	};
};

extern VApi void VLog(const char* fmt, ...);
extern VApi void VError(const char* fmt, ...);

#define VLOG VLog
#define VERROR VError


#endif
